/**
  ***********************************************************************************
  * @file   : Service_Communication.cpp
  * @brief  : Communication support file.This file provides access ports to interface
  *           with connected devices.
  ***********************************************************************************
  *
**/
/* Includes ------------------------------------------------------------------*/
#include "Service_Communication.h"
#include "Serial_Plot.h"
#include "Service_Module.h"
#include "Service_Operation.h"
#include "Service_Debug.h"
#include "shoot.h"
#include "chassis.h"
#include "pan_tilt.h"
#include "vision.h"

#define USART6_RX_BUFFER_SIZE 300
uint8_t Uart6_Rx_Buff[USART6_RX_BUFFER_SIZE];
uint32_t Referee_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen);

#define PAN_TILT_AHRS_RX_BUFFER_SIZE 50
uint8_t PAN_TILT_AHRS_Rx_Buff[PAN_TILT_AHRS_RX_BUFFER_SIZE];
uint32_t PAN_TILT_AHRS_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen);

#define USART8_RX_BUFFER_SIZE 32
uint8_t Uart8_Rx_Buff[USART8_RX_BUFFER_SIZE];
uint32_t SuperCap_call_back(uint8_t *buf, uint16_t len)
{
    SuperCap.update(buf);
    return 0;
}

extern C_VISION Manifold;
#define MANIFOLD_RX_BUFFER_SIZE 50
uint8_t MANIFOLD_Rx_Buff[MANIFOLD_RX_BUFFER_SIZE];
uint32_t MANIFOLD_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    Manifold.update(Recv_Data);
    return 0;
}

/**
* @brief  Initialization of communication service
* @param  None.
* @return None.
*/
void Service_Communication_Init(void)
{
    serial_plot.Uart_init(&huart2);
    DR16_Uart_Init();
    Uart_Init(&huart6, Uart6_Rx_Buff, USART6_RX_BUFFER_SIZE, Referee_recv_Callback);
    Uart_Init(&huart7, PAN_TILT_AHRS_Rx_Buff, PAN_TILT_AHRS_RX_BUFFER_SIZE, PAN_TILT_AHRS_recv_Callback);
    // Uart_Init(&huart8, Uart8_Rx_Buff, USART8_RX_BUFFER_SIZE, SuperCap_call_back);

    Uart_Init(&huart3, MANIFOLD_Rx_Buff, MANIFOLD_RX_BUFFER_SIZE, MANIFOLD_recv_Callback);

    // Uart_Init(&huart3, Uart3_Rx_Buff, USART3_RX_BUFFER_SIZE,NULL);
    // Uart_Init(&huart4, Uart4_Rx_Buff, USART4_RX_BUFFER_SIZE,NULL);
    // Uart_Init(&huart5, Uart5_Rx_Buff, USART5_RX_BUFFER_SIZE,NULL);
    // Uart_Init(&huart6, PackFromVisionUnion.UsartData, 40,&GetViaionData);
    // Uart_Init(&huart1, PackFromVisionUnion.UsartData, 15,&GetViaionData);
    // Uart_Init(&huart6, Uart1_Rx_Buff, USART1_RX_BUFFER_SIZE,RecHandle);
    CAN_Init(&hcan1, User_CAN1_RxCpltCallback);
    CAN_Init(&hcan2, User_CAN2_RxCpltCallback);

    /* CAN Filter Config*/
    CAN_Filter_Mask_Config(&hcan1, CanFilter_1 | CanFifo_0 | Can_STDID | Can_DataType, 0x201, 0x3FF);   //c620
    

    CAN_Filter_Mask_Config(&hcan1, CanFilter_5 | CanFifo_0 | Can_STDID | Can_DataType, 0x205, 0x3FF);   //云台yaw 6020
    CAN_Filter_Mask_Config(&hcan2, CanFilter_19 | CanFifo_0 | Can_STDID | Can_DataType, 0x206, 0x3ff);  //云台pitch 6020
    
    CAN_Filter_Mask_Config(&hcan2, CanFilter_20 | CanFifo_0 | Can_STDID | Can_DataType, 0x202, 0x3ff);  //拨盘 c610
    CAN_Filter_Mask_Config(&hcan2, CanFilter_21 | CanFifo_0 | Can_STDID | Can_DataType, 0x203, 0x3ff);  //摩擦轮 c620
    CAN_Filter_Mask_Config(&hcan2, CanFilter_22 | CanFifo_0 | Can_STDID | Can_DataType, 0x204, 0x3ff);  //摩擦轮 c620

    CAN_Filter_Mask_Config(&hcan1, CanFilter_10 | CanFifo_0 | Can_STDID | Can_DataType, 0x210, 0x3ff); //超级电容

    // CAN_Filter_Mask_Config(&hcan1, CanFilter_4 | CanFifo_0 | Can_STDID | Can_DataType, 0x201, 0x3FF);	//拨盘 c610
    // CAN_Filter_Mask_Config(&hcan2, CanFilter_15 | CanFifo_0 | Can_STDID | Can_DataType, 0x206, 0x3ff);   //yaw 6020
    // CAN_Filter_Mask_Config(&hcan2, CanFilter_17 | CanFifo_0 | Can_STDID | Can_DataType, 0x221, 0x3ff);	//板间通信上行int数据
    // CAN_Filter_Mask_Config(&hcan2, CanFilter_19 | CanFifo_0 | Can_STDID | Can_DataType, 0x220, 0x3ff);	//板间通信上行float数据
}

/**
* @brief  Callback function in CAN Interrupt
* @param  None.
* @return None.
*/
void User_CAN1_RxCpltCallback(CAN_RxBuffer *CAN_RxMessage)
{
	switch(CAN_RxMessage->header.StdId)
	{
		case 0x201:
            Wheel[0].update(CAN_RxMessage->data);
            break;
		
        case 0x205:
            YawMotor.update(CAN_RxMessage->data);
            break;
        case 0x210:
            SuperCap.update(CAN_RxMessage->data);
            break;
    }
}

void User_CAN2_RxCpltCallback(CAN_RxBuffer *CAN_RxMessage)
{
	switch(CAN_RxMessage->header.StdId)
	{
        case 0x202:
            DriveplateMotor.update(CAN_RxMessage->data);
        break;
        case 0x203:
            FrictionMotor[0].update(CAN_RxMessage->data);
        break;
        case 0x204:
            FrictionMotor[1].update(CAN_RxMessage->data);
        break;
        case 0x206:
            PitchMotor.update(CAN_RxMessage->data);
        break;
    }
}

// /**
// * @brief  Data convertion，provide lower layer access port 
//           for application layer.
// * @param  CAN_RxMsg：Lower layer CAN frame.
//           CAN_RxCOB：Application layer CAN Frame.
// * @return None.
// */
// static void Convert_Data(CAN_RxMessage* input, COB_TypeDef* output)
// {
//   output->ID = input->header.StdId;
//   output->DLC = input->header.DLC;
//   memcpy(output->Data, input->data, output->DLC);
// }

uint32_t Referee_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    static BaseType_t *pxHigherPriorityTaskWoken;
    static USART_COB referee_pack;
    //	static uint8_t temp_buff[256];

    if (RecvReferee_Handle != NULL && ReceiveLen < 256)
    {
        referee_pack.address = Recv_Data;
        referee_pack.len = ReceiveLen;
        xTaskNotifyFromISR(RecvReferee_Handle, (uint32_t)&referee_pack, eSetValueWithOverwrite, pxHigherPriorityTaskWoken);
    }
    return 0;
}

uint32_t PAN_TILT_AHRS_recv_Callback(uint8_t *Recv_Data, uint16_t ReceiveLen)
{
    pan_tilt_AHRS.DataCapture(Recv_Data, ReceiveLen);
    return 0;
}

/************************ COPYRIGHT(C) USTC-ROBOWALKER **************************/
